package com.bytz.modules.cms.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bytz.common.exception.BytzBootException;
import com.bytz.common.system.base.service.impl.AbstractCrudService;
import com.bytz.modules.cms.order.entity.Order;
import com.bytz.modules.cms.order.entity.OrderFlowRuleTestCase;
import com.bytz.modules.cms.order.entity.OrderItem;
import com.bytz.modules.cms.order.mapper.OrderFlowRuleTestCaseMapper;
import com.bytz.modules.cms.order.model.AdminOrderModel;
import com.bytz.modules.cms.order.model.OrderFlowRuleTestCaseSaveRo;
import com.bytz.modules.cms.order.model.OrderItemModel;
import com.bytz.modules.cms.order.service.IOrderFlowRuleTestCaseService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

/**
 * 订单流程规则测试用例服务
 * @author shanxuezhong
 */
@Service
public class OrderFlowRuleTestCaseServiceImpl extends AbstractCrudService<OrderFlowRuleTestCaseMapper, OrderFlowRuleTestCase, OrderFlowRuleTestCaseSaveRo> implements IOrderFlowRuleTestCaseService {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    protected void saveDataValid(OrderFlowRuleTestCaseSaveRo saveRo) {
        try {
            saveRo.setCaseDataOrder(objectMapper.writeValueAsString(saveRo.getOrder()));
            List<OrderItemModel> orderItems = Optional.ofNullable(saveRo.getOrderItems()).orElse(Collections.emptyList());
            saveRo.setCaseDataOrderItem(objectMapper.writeValueAsString(orderItems));
        } catch (JsonProcessingException ex) {
            throw new BytzBootException("序列化测试数据时出错：" + ex.getMessage(), ex);
        }
    }

    @Override
    protected OrderFlowRuleTestCaseSaveRo insertSaveObject(OrderFlowRuleTestCaseSaveRo saveRo) {
        save(saveRo);

        return saveRo;
    }

    @Override
    protected OrderFlowRuleTestCaseSaveRo updateSaveObject(OrderFlowRuleTestCaseSaveRo saveRo) {
        updateById(saveRo);

        return saveRo;
    }

    @Override
    protected OrderFlowRuleTestCaseSaveRo saveOthers(OrderFlowRuleTestCaseSaveRo saveRo) {
        return saveRo;
    }

    @Override
    protected boolean deleteEntity(OrderFlowRuleTestCase entity) {
        return removeById(entity);
    }

    @Override
    protected void deleteOthers(OrderFlowRuleTestCase entity) {

    }

    @Override
    public IPage<OrderFlowRuleTestCase> queryPage(Page<OrderFlowRuleTestCase> page, QueryWrapper<OrderFlowRuleTestCase> initQueryWrapper) {
        initQueryWrapper.lambda().select(
                OrderFlowRuleTestCase::getId,
                OrderFlowRuleTestCase::getCaseName,
                OrderFlowRuleTestCase::getRemark,
                OrderFlowRuleTestCase::getCreateTime);

        return page(page, initQueryWrapper);
    }

    @Override
    @SuppressWarnings("unchecked")
    public OrderFlowRuleTestCaseSaveRo getSaveRoById(String id) throws Exception {
        OrderFlowRuleTestCase testCase = getById(id);
        if (testCase == null) {
            throw new BytzBootException("找不到测试用例");
        }

        // 复制数据到结果，其中序列化的字符串不返回
        OrderFlowRuleTestCaseSaveRo result =BeanUtil.toBean(testCase,
                OrderFlowRuleTestCaseSaveRo.class,
                CopyOptions.create().setIgnoreProperties(
                        OrderFlowRuleTestCaseSaveRo::getCaseDataOrder,
                        OrderFlowRuleTestCaseSaveRo::getCaseDataOrderItem));

        if (StrUtil.isNotBlank(testCase.getCaseDataOrder())) {
            result.setOrder(objectMapper.readValue(testCase.getCaseDataOrder(), AdminOrderModel.class));
        } else {
            result.setOrder(new AdminOrderModel());
        }

        if (StrUtil.isNotBlank(testCase.getCaseDataOrderItem())) {
            result.setOrderItems(objectMapper
                    .readerForListOf(OrderItemModel.class)
                    .readValue(testCase.getCaseDataOrderItem()));
        } else {
            result.setOrderItems(ListUtil.empty());
        }

        return result;
    }
}